在bootcamps controller中,CRUD 函式目前都是以try & catch 來處理錯誤
我們可以透過撰寫wrapper function來簡化不停重複的try & catch block
在middleware資料夾中新增async.js file:
const asyncHandler = fn => (req, res, next) => {
Promise.resolve(fn(req, res, next)).catch(next);
}
之後再把asyncHandler包在async function外就ok了~
在昨天的CRUD API中,我們可以分為兩個部分來處理錯誤:
第一種情況比較好處理,只需要新增errorResponse.js file
class ErrorResponse extends Error {
constructor(message, statusCode) {
super(message);
this.statusCode = statusCode;
}
}
值得注意的是,message繼承來自Error的property
透過擴展Error,我們可以在我們創建的錯誤中獲得預先構建的功能,這些功能可能會在某些情況下需要
在'./controllers/bootcamps.js'中處理第一種情況:
if (!bootcamp) {
return next(new ErrorResponse(`Bootcamp not found with id of ${req.params.id}`, 404));
}
其他常見的錯誤,我們可以再分成三種情況討論:
第一種情況,回傳的err.name會顯示為CastError
if (err.name === 'CastError') {
const message = `Resource not found with id of ${err.value}`;
error = new ErrorResponse(message, 404);
}
第二種情況,會回傳E11000 duplicate key error
if (err.code === 11000) {
const message = 'Duplicate field value entered';
error = new ErrorResponse(message, 400);
}
第三種情況為mongoose validation error,我們要的資訊是回傳err.errors object的message
if (err.name === 'ValidationError') {
const message = Object.values(err.errors).map(val => val.message);
error = new ErrorResponse(message, 400);
}
最後在回傳statusCode & error.message就完成啦!